home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
polyview
/
polyvw31.lha
/
Polyview3.1
/
new
/
pvraster.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-24
|
14KB
|
447 lines
/*****************************************************************************
* NCSA Polyview 3.1 *
* *
* Version 3.1 changes and additions by Gilles Bourhis. *
* Version 3 changes and additions by Marc Andreessen. *
* Version 2 by Brian Calvert. *
* *
* Software Development Group *
* National Center for Supercomputing Applications *
* University of Illinois at Urbana-Champaign *
* *
* This is BETA release software. As such it may contain software bugs and *
* exhibit inconsistencies. *
* *
* Please send bug reports to polyview@ncsa.uiuc.edu. *
* *
* Copyright (c) 1992 The Board of Trustees of the University of Illinois. *
* *
* Permission to use, copy, and modify this software and its *
* documentation for educational, research, and non-profit purposes is *
* hereby granted, provided that the above copyright notice, the original *
* authors names, and this permission notice appear in all such copies. *
* Any distribution of this software requires the explicit and written *
* authorization of the authors. *
* *
* The University of Illinois makes no representations about the *
* suitability of this software for any purpose. It is provided "as is" *
* without warranty of any kind. *
*****************************************************************************/
/* $Id: pvraster.c,v 1.3 93/08/24 10:27:43 gbourhis Exp $ */
#ifdef RCSLOG
$Log: pvraster.c,v $
* Revision 1.3 93/08/24 10:27:43 gbourhis
* replace version string from 3.0 to 3.1
*
* Revision 1.2 93/06/24 16:34:16 gbourhis
* add some casting to parameter of HDF routines.
*
* Revision 1.1 92/09/18 10:55:26 marca
* Initial revision
*
#endif
#include "pv.h"
#include "net.h"
#define QUANT_SUPPORT
#ifdef QUANT_SUPPORT
extern unsigned char *Ir, *Ig, *Ib;
extern int quant_size;
extern int K;
extern short int *Qadd;
extern unsigned char lut_r[256], lut_g[256], lut_b[256];
extern int doquant();
#endif
extern int NetSendRaster8Group
(NetPort *, char *, unsigned char *, int, int, unsigned char *, int,
int, char *);
int WriteRaster(state_t *state, window_t *win, char *outfile)
{
unsigned long *sgiimage;
unsigned char *hdfimage;
static unsigned char palette[768];
int i, j;
int width, height;
int rv;
static Matrix m;
char base[MAXPATHLEN];
char full[MAXPATHLEN];
polyview_t *pv;
if (win->type != POLYVIEW)
return ST_ERROR;
/* Set up initial data structures. */
width = WIN_WIDTH(win) - 2;
height = WIN_HEIGHT(win) - 2;
sgiimage = (unsigned long *)malloc (width * height * sizeof (unsigned long));
hdfimage = (unsigned char *)malloc (width * height * sizeof (unsigned char));
/* Generate the filename and update count. */
strsub(base, WIN_RASTERNAME(win), ".hdf", "");
sprintf(full, "%s%04d.hdf", base, WIN_RASTERNUM(win));
WIN_RASTERNUM(win)++;
/* Tell the user that the grab is beginning. */
stprintf(state, "Reading %s image...", WIN_NAME(win));
/* Focus on the right window. */
pv = (polyview_t *)WIN_IMAGE(win);
XmxWinset (pv->drawing_volume);
/* Save the projection matrix. */
mmode (MPROJECTION);
getmatrix (m);
mmode (MVIEWING);
/* Save the viewport. */
pushviewport ();
/* Read the image; screenspace loads the viewport and does
an ortho2, which loads the projection matrix in MVIEWING mode. */
readsource (SRC_FRONT);
screenspace ();
lrectread (1, 1, width, height, sgiimage);
/* Restore the projection matrix. */
mmode (MPROJECTION);
loadmatrix (m);
mmode (MVIEWING);
/* Restore the viewport. */
popviewport ();
/* With QUANT_SUPPORT enabled, the quantization algorithm by Wu */
#ifdef QUANT_SUPPORT
Ir = (unsigned char *)malloc (width * height * sizeof (unsigned char));
Ig = (unsigned char *)malloc (width * height * sizeof (unsigned char));
Ib = (unsigned char *)malloc (width * height * sizeof (unsigned char));
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
{
Ir[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x000000ff);
Ig[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x0000ff00) >> 8;
Ib[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x00ff0000) >> 16;
}
quant_size = width * height;
K = 200;
doquant ();
/* Ir/Ig/Ib freed in doquant */
/* Now lut_r, lut_g, lut_b are LUT contents,
and Qadd is the quantized image. */
for (i = 0; i < (width * height); i++)
hdfimage[i] = Qadd[i];
free (Qadd);
for (i = 0; i < 256; i++)
{
palette[i*3+0] = lut_r[i];
palette[i*3+1] = lut_g[i];
palette[i*3+2] = lut_b[i];
}
#else /* not QUANT_SUPPORT */
/* Convert to hdf colorindex format. We want 3-3-2 dithering. */
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
hdfimage[(height-j-1)*width+i] =
(
(((sgiimage[j*width+i] & 0x000000ff) >> (8 - 3))) |
(((sgiimage[j*width+i] & 0x0000ff00) >> (8 + 8 - 3)) << 3) |
(((sgiimage[j*width+i] & 0x00ff0000) >> (16 + 8 - 2)) << 6)
);
/* Construct 3-3-2 RGB palette. */
for (i = 0; i < 256; i++)
{
/* Red value is low-order three bits = 1 + 2 + 4,
shifted into upper three bits. */
palette[i*3+0] = ((unsigned char)i & (unsigned char)7) << 5;
/* Green value is middle three bits = 8 + 16 + 32,
shifted into upper three bits. */
palette[i*3+1] = ((unsigned char)i & (unsigned char)56) << 2;
/* Blue value is upper two bits = 64 + 128,
shifted into upper two bits. */
palette[i*3+2] = ((unsigned char)i & (unsigned char)192);
}
#endif /* not QUANT_SUPPORT */
/* Tell the user that the image is being written. */
stprintf(state, "Writing %s image to '%s'...", WIN_NAME(win), full);
/* Set the palette for the file. */
DFR8setpalette(palette);
/* Write the image to the file. */
DFR8putimage(full, (char *)hdfimage, width, height, DFTAG_RLE);
/* Tell the user that the image is being written. */
stprintf(state, "Image write complete...");
/* Free the memory buffers. */
free (hdfimage);
free (sgiimage);
return ST_OKAY;
}
/* Make sure we don't super-quantize DTM stuff. */
#undef QUANT_SUPPORT
/* This is the new WriteRaster which writes via a DTM outport
rather than to a file. This should be renamed COMsendRaster
or something similar. */
int WriteRasterOverDTM (state_t *state, window_t *win)
{
unsigned long *sgiimage;
unsigned char *hdfimage;
static unsigned char palette[768];
int i, j;
int width, height;
int rv;
static Matrix m;
polyview_t *pv;
if (win->type != POLYVIEW)
return ST_ERROR;
/* Set up initial data structures. */
width = WIN_WIDTH(win);
height = WIN_HEIGHT(win);
sgiimage = (unsigned long *)malloc (width * height * sizeof (unsigned long));
hdfimage = (unsigned char *)malloc (width * height * sizeof (unsigned char));
/* Focus on the right window. */
pv = (polyview_t *)WIN_IMAGE(win);
XmxWinset (pv->drawing_volume);
/* Save the projection matrix. */
mmode (MPROJECTION);
getmatrix (m);
mmode (MVIEWING);
/* Save the viewport. */
pushviewport ();
/* Read the image; screenspace loads the viewport and does
an ortho2, which loads the projection matrix in MVIEWING mode. */
readsource (SRC_FRONT);
screenspace ();
lrectread (0, 0, width - 1, height - 1, sgiimage);
/* Restore the projection matrix. */
mmode (MPROJECTION);
loadmatrix (m);
mmode (MVIEWING);
/* Restore the viewport. */
popviewport ();
#ifdef QUANT_SUPPORT
Ir = (unsigned char *)malloc (width * height * sizeof (unsigned char));
Ig = (unsigned char *)malloc (width * height * sizeof (unsigned char));
Ib = (unsigned char *)malloc (width * height * sizeof (unsigned char));
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
{
Ir[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x000000ff);
Ig[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x0000ff00) >> 8;
Ib[(height-j-1)*width+i] =
(sgiimage[j*width+i] & 0x00ff0000) >> 16;
}
quant_size = width * height;
K = 200;
doquant ();
/* Ir/Ig/Ib freed in doquant */
/* Now lut_r, lut_g, lut_b are LUT contents,
and Qadd is the quantized image. */
for (i = 0; i < (width * height); i++)
hdfimage[i] = Qadd[i] + 32;
free (Qadd);
for (i = 0; i < 200; i++)
{
palette[(i+32)*3+0] = lut_r[i];
palette[(i+32)*3+1] = lut_g[i];
palette[(i+32)*3+2] = lut_b[i];
}
#else /* not QUANT_SUPPORT */
/* Convert to hdf colorindex format. We want 3-3-2 dithering. */
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
hdfimage[(height-j-1)*width+i] =
(
(((sgiimage[j*width+i] & 0x000000ff) >> (8 - 3))) |
(((sgiimage[j*width+i] & 0x0000ff00) >> (8 + 8 - 3)) << 3) |
(((sgiimage[j*width+i] & 0x00ff0000) >> (16 + 8 - 2)) << 6)
);
/* Construct 3-3-2 RGB palette. */
for (i = 0; i < 256; i++)
{
/* Red value is low-order three bits = 1 + 2 + 4,
shifted into upper three bits. */
palette[i*3+0] = ((unsigned char)i & (unsigned char)7) << 5;
/* Green value is middle three bits = 8 + 16 + 32,
shifted into upper three bits. */
palette[i*3+1] = ((unsigned char)i & (unsigned char)56) << 2;
/* Blue value is upper two bits = 64 + 128,
shifted into upper two bits. */
palette[i*3+2] = ((unsigned char)i & (unsigned char)192);
}
#endif /* not QUANT_SUPPORT */
/* Blast across the network. */
/* outport can be NULL here; the net module will send the
message to all output ports. */
rv = NetSendRaster8Group
(NULL, "Polyview 3.1 Image", hdfimage, width, height, palette, TRUE,
FALSE, NULL);
/* Announce results in the status window. */
if (rv == -1)
stprintf (state, "ERROR broadcasting raster image.");
else
/* Dave says rv == 0 is also okay. */
stprintf (state, "Raster image transmission successful.");
free (sgiimage);
free (hdfimage);
return ST_OKAY;
}
int ReadHDFPalette(state_t *state, window_t *win, char *infile)
{
short *polypalette;
unsigned char palette[768];
int i;
/* Read the palette from the file. */
if (DFPgetpal(infile, (char *)palette) == -1)
{
stprintf(state, "ERROR: Problem reading palette from '%s'.\n", infile);
return ST_ERROR;
}
/* Convert the palette to PolyView format. */
for (polypalette = (short *) WIN_PALETTE(win)->master_palette, i = 0;
i < 768; i++, polypalette++)
*polypalette = (short) palette[i];
DFPrestart();
cm_reset(state, win);
return ST_OKAY;
}
int ReadRawPalette(state_t *state, window_t *win, char *infile)
{
int i;
char red[256], blue[256], green[256]; /* character arrays that */
/* contain palette rgb values */
FILE *fp; /* palette file to be used */
if ((fp = fopen(infile, "r")) != NULL)
{
/* Read in the raw palette from palette file */
fread(red,1,256,fp);
fread(green,1,256,fp);
fread(blue,1,256,fp);
fclose(fp);
/* Copy colors into palette array for display */
for (i = 0; i < 256; i++) {
WIN_PALETTE(win)->master_palette[i][R] =(short)red[i];
WIN_PALETTE(win)->master_palette[i][G] =(short)green[i];
WIN_PALETTE(win)->master_palette[i][B] =(short)blue[i];
}
}
else
{
stprintf(state, "ERROR: Problem reading palette from '%s'.\n", infile);
return ST_ERROR;
}
cm_reset(state, win);
return ST_OKAY;
}
int WriteHDFPalette(state_t *state, window_t *win, char *outfile)
{
short *polypalette;
unsigned char palette[768];
int i;
/* Convert the palette to HDF format. */
for (polypalette = (short *) WIN_PALETTE(win)->display_palette, i = 0;
i < 768; i++, polypalette++)
palette[i] = (unsigned char) *polypalette;
/* Write the palette out to the file. */
if (DFPputpal(outfile, (char *)palette, 0, "w") == 0)
return ST_OKAY;
else
{
stprintf(state, "ERROR: Problem writing palette to '%s'.\n", outfile);
return ST_ERROR;
}
}
int WriteRawPalette(state_t *state, window_t *win, char *outfile)
{
int i;
char red[256], blue[256], green[256]; /* character arrays that */
/* contain palette rgb values */
FILE *fp; /* palette file to be used */
if ((fp = fopen(outfile, "w")) != NULL)
{
/* Copy palette into arrays for writing. */
for (i = 0; i < 256; i++)
{
red[i] = (char)WIN_PALETTE(win)->display_palette[i][R];
green[i] =(char)WIN_PALETTE(win)->display_palette[i][G];
blue[i] = (char)WIN_PALETTE(win)->display_palette[i][B];
}
/* Write the raw palette to the file. */
fwrite(red,1,256,fp);
fwrite(green,1,256,fp);
fwrite(blue,1,256,fp);
fclose(fp);
return ST_OKAY;
}
else
{
stprintf(state, "ERROR: Problem writing palette to '%s'.\n", outfile);
return ST_ERROR;
}
}